package model.semantics;

import java.util.ArrayList;
import java.util.Collection;

import model.RGBColor;
/**
 * Defines a general method for combining three values together.
 * 
 * Currently only serves Color but additional ternary operations can be added.
 * 
 * @author Robert C Duvall
 * @author Anne Weng
 * @author Troy Ferrell
 */
public class TernaryOperation extends OperationToken
{	
	public TernaryOperation(int precedence)
	{
		super(precedence);
		myNumArguments = 3;
	}

	@Override
	public boolean addChild(AbstractToken o)
	{
		if(myChildren.size() < 3)
    	{
    		myChildren.add(o);
    		return true;
    	}
    	else
    	{
    		return false;
    	}
	}

	@Override
	public Collection<AbstractToken> getChildren()
	{
		return myChildren;
	}

	@Override
	protected RGBColor evaluateSafely (RGBColor[] colors)
    {
		ArrayList<AbstractToken> childrenList = new ArrayList<AbstractToken>(myChildren);
    	RGBColor colorLeft = childrenList.get(0).evaluate(colors);
    	RGBColor colorMid = childrenList.get(1).evaluate(colors);
    	RGBColor colorRight = childrenList.get(2).evaluate(colors);
    	
    	return evaluateColor(colorLeft, colorMid, colorRight);
    }


    /**
     * Given two colors, combine them to create a single color.
     * 
     * By default, combines each color component in the same manner.  Override
     * this method to operate directly on the colors, rather than their components. 
     */
    protected RGBColor evaluateColor (RGBColor first, RGBColor second, RGBColor third)
    {
        return new RGBColor(evaluateValue(first.getRed(), second.getRed(), third.getRed()), 
                            evaluateValue(first.getGreen(), second.getGreen(), third.getGreen()),
                            evaluateValue(first.getBlue(), second.getBlue(), third.getBlue()));
    }


    /**
     * Given two values, combine them to create a single value.
     * 
     * There is no reasonable default value to return and this method should not
     * be abstract so throw an exception if neither evaluate method is overridden.
     */
    protected double evaluateValue (double first, double second, double third)
    {
        throw new UnsupportedOperationException();
    }

}
